﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using SMS.Properties;
using System.Xml.Linq;
using System.Xml;
using SMS_Gateway;
using System.Web;

namespace SMS
{
    enum SMSStatus
    {
        English,
        Unicode
    }

    public partial class frmMain : Form
    {
        const int MAX_ENG_Length = 160;
        const int MAX_ARA_Length = 70;

        SMSStatus state;
        public Gateway _gateway;
        public Credentials _cred;

        public frmMain()
        {
            InitializeComponent();

            //to be changed
            _gateway = new SMSGobalGateway("CHFCI"); //TODO : Make it a setting or something


            try
            {
                contacts.ReadXml(Settings.Default.XSDpath, XmlReadMode.Auto);

            }
            catch (Exception)
            {

            }
            //------------------



        }

        private void btnSend_Click(object sender, EventArgs e)
        {

            ShortMessageGenerator.SetMessage(txtMessage.Text);

            if (!ValidateTextMessage())
            {
                return;
            }

            List<SMSContact> unreachableContacts= new List<SMSContact>();
            int NoOfSuccessfulSMS = 0;

            if (dgContacts.SelectedRows.Count == 0)
            {
                MessageBox.Show("Please Select the contacts that you're going to send messages to");
            }
            else
            {
                try
                {
                    // Send an SMS message
                    OpenConnection();

                    bool unicode = (state == SMSStatus.Unicode);
                    //   string smsc = chkSMSC.Checked ? txtSMSC.Text : string.Empty;


                    foreach (DataGridViewRow row in dgContacts.SelectedRows)
                    {

                        // Personalization

                        ContactsDS.ContactsRow contactrow = (row.DataBoundItem as DataRowView).Row as ContactsDS.ContactsRow;


                        String personalizedMessage = ShortMessageGenerator.Generate(new List<string>() { GetFirstName(contactrow.Name), contactrow.Phone });
                        SingleSMS sms = new SingleSMS(personalizedMessage);
                        SMSContact contact = new SMSContact(contactrow.Phone);

                        Log(personalizedMessage);

                        // ---------------------------

                        bool sendingResult = _gateway.SendSingleSMSTo(_cred, sms, contact, unicode);

                        if (!sendingResult)
                        {
                            unreachableContacts.Add(contact);
                        }
                        else
                        {
                            NoOfSuccessfulSMS++;
                        }

                        Log(String.Format("- SMS to :{0} is sent successfully", contactrow.Name));
                        
                    }

                    if (unreachableContacts.Count != 0)
                    {
                        string message=String.Format("{0} SMS were sent successfully , the following numbers were unreachable\n{1}",NoOfSuccessfulSMS,String.Join(",",unreachableContacts.Select<SMSContact,string>(x=>x.Number).ToArray())); 

                        MessageBox.Show( message, "Some contacts failed to be contacted", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        MessageBox.Show(String.Format("All {0} SMS were sent successfully",NoOfSuccessfulSMS), "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }

                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    
                }
            }

        }

        private void Log(string logMessage)
        {
            txtLog.AppendText(logMessage);
            txtLog.AppendText("\n");
        }

        private bool ValidateTextMessage()
        {
            if (txtMessage.Text != null)
            {
                if (dgContacts.SelectedRows.Count != 0)
                {
                    foreach (DataGridViewRow row in dgContacts.SelectedRows)
                    {
                        ContactsDS.ContactsRow contact = (row.DataBoundItem as DataRowView).Row as ContactsDS.ContactsRow;

                        String personalizedMessage = ShortMessageGenerator.Generate(new List<string>() { GetFirstName(contact.Name), contact.Phone });

                        if (((this.state == SMSStatus.English) && (personalizedMessage.Length > MAX_ENG_Length)) || ((this.state == SMSStatus.Unicode) && (personalizedMessage.Length > MAX_ARA_Length)))
                        {
                            epText.SetError(txtMessage, String.Format("Contact Name {0} is too long for the current template you have to remove {1} Characters in order to send successfully !", contact.Name));
                            return false;
                        }

                    }
                }

                epText.Clear();
                return true;
            }
            else
            {
                epText.SetError(txtMessage, "Text cannot be empty");
                return false;
            }

        }

        private void OpenConnection()
        {
            if (!_gateway.IsConnected || (_cred == null) )
            {
                throw new Exception("You're Not Logged in, or credentials were not provided");
            }
        }





        private void txtMessage_TextChanged(object sender, EventArgs e)
        {
            CheckUnicode_ChangeSMSStatus();



        }

        private void CheckUnicode_ChangeSMSStatus()
        {
            String s = Encoding.ASCII.GetString(Encoding.Convert(Encoding.Default, Encoding.ASCII, Encoding.ASCII.GetBytes(txtMessage.Text)));
            changeState((s == txtMessage.Text.ToString()) ? SMSStatus.English : SMSStatus.Unicode);


            lblCounter.Text = (((this.state == SMSStatus.English) ? MAX_ENG_Length : MAX_ARA_Length) - txtMessage.Text.Length).ToString() + " Remaining";

        }

        private void changeState(SMSStatus state)
        {
            this.state = state;
            switch (state)
            {
                case SMSStatus.English:
                    lblLanguage.Text = "English";
                    txtMessage.MaxLength = MAX_ENG_Length;
                    break;
                case SMSStatus.Unicode:
                    lblLanguage.Text = "Unicode";
                    txtMessage.MaxLength = MAX_ARA_Length;
                    if (txtMessage.Text.Length > MAX_ARA_Length)
                    {
                        txtMessage.Text = txtMessage.Text.Remove(MAX_ARA_Length - 1);
                        txtMessage.SelectionStart = MAX_ARA_Length - 1;
                    }
                    break;
                default:
                    break;
            }



        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(txtName.Text))
            {
                epName.SetError(this.txtName, "Name can't be empty");
            }
            else
                if (String.IsNullOrEmpty(txtNumber.Text))
                {
                    epName.SetError(this.txtNumber, "Number can't be empty");
                }
                else
                {
                    epName.Clear();
                    String name = txtName.Text;
                    String number = txtNumber.Text;
                    AddContact(name, number);
                }
        }

        private void AddContact(String name, String number)
        {
            contacts.Contacts.AddContactsRow(name, number);
        }

        private void Save()
        {
            contacts.AcceptChanges();
            contacts.WriteXml(Settings.Default.XSDpath);
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Sure to delete ?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
            {
                contactsBindingSource.RemoveCurrent();
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(Settings.Default.XSDpath))
            {
                if (dlgSave.ShowDialog() == DialogResult.OK)
                {
                    Settings.Default.XSDpath = dlgSave.FileName;
                }
                Save();
            }
            else
            {
                Save();
            }
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConnectToService();

        }

        private void ConnectToService()
        {
            CloseConnection();

            frmSettings frmSettings = new frmSettings();
            frmSettings.Owner = this;
            frmSettings.ShowDialog();

            if (_gateway == null)
            {
                DisableSMS();

            }
            else
            {
                EnableSMS();
            }
        }

        private void EnableSMS()
        {
            splitContainer.Panel1.Enabled = true;
            lblNotifier.Text = "Connected";
            lblNotifier.Font = new Font("Tahoma", 14, FontStyle.Bold);
            lblNotifier.ForeColor = Color.Green;
        }

        private void DisableSMS()
        {
            splitContainer.Panel1.Enabled = false;
            lblNotifier.Text = "Disconnected";
            lblNotifier.Font = new Font("Tahoma", 14, FontStyle.Bold);
            lblNotifier.ForeColor = Color.Red;
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            CloseConnection();
        }

        private void CloseConnection()
        {
            if (_gateway != null && _gateway.IsConnected)
            {
                if (_gateway.GetType() == typeof(SOAPGateway))
                {
                    ((SOAPGateway)_gateway).LogOut();
                }
            }
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            ConnectToService();
            CheckUnicode_ChangeSMSStatus();

        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (dlgOpen.ShowDialog() == DialogResult.OK)
            {
                //Change Settings 
                Settings.Default.XSDpath = dlgOpen.FileName;
                Settings.Default.Save();

                //open File
                contacts.Clear();
                contacts.ReadXml(dlgOpen.FileName);
            }
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (dlgSave.ShowDialog() == DialogResult.OK)
            {
                contacts.WriteXml(dlgSave.FileName);
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox box = new AboutBox();
            box.ShowDialog();
        }


        private void smiPaste_Click(object sender, EventArgs e)
        {
            // does it have header ? 
            string s = Clipboard.GetText();
            // Clipboard.GetText();



            //MessageBox.Show(s);
            try
            {
                string[] arr = s.Split('\n');


                int Lastcolindex = arr[0].Split('\t').Count() - 1;
                int NamecolIndex = 0;
                int NumberColIndex = Lastcolindex;
                int start = (MessageBox.Show("Does data contain a header row ?", "Header", MessageBoxButtons.YesNo) == DialogResult.Yes) ? 1 : 0;

                int f;
                if (!int.TryParse(arr[start].Split('\t')[NumberColIndex], out f))
                {
                    NamecolIndex = Lastcolindex;
                    NumberColIndex = 0;
                }


                for (int i = start; i < arr.Length; i++)
                {
                    string[] subarr = arr[i].Split('\t');
                    if (subarr.Count() < 2)
                    {
                        MessageBox.Show("Some Illegal row came on the data");
                        continue;
                    }
                    if (string.IsNullOrEmpty(subarr[NamecolIndex]) || string.IsNullOrEmpty(subarr[NumberColIndex]))
                    {
                        continue;
                    }

                    String name = subarr[NamecolIndex];
                    String number = "0" + int.Parse(subarr[NumberColIndex]).ToString();



                    AddContact(name, number);

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\nData might not be inserted correctly");
            }

        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Settings.Default.XSDpath = null;
            contacts.Contacts.Clear();
        }

        private void btntest_Click(object sender, EventArgs e)
        {
            UnicodeEncoding enc = new UnicodeEncoding();
            byte[] arr = Encoding.Convert(enc, Encoding.GetEncoding("ISO-8859-1"), Encoding.Unicode.GetBytes(txtMessage.Text));
            string s = Encoding.GetEncoding("ISO-8859-1").GetString(arr);

            MessageBox.Show(s);

        }

        private string GetFirstName(String name)
        {
            return name.Split(' ')[0];
        }


    }
}
